﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 独立钻石
{
    /// <summary>
    /// 局面
    /// </summary>
    public class Aspect
    {
        /// <summary>
        /// 当前棋局
        /// </summary>
        public bool[,] map;

        /// <summary>
        /// 上一个棋局
        /// </summary>
        public Aspect parent = null;

        /// <summary>
        /// 当前步数
        /// </summary>
        public int th = 0;

        /// <summary>
        /// 当前棋步
        /// </summary>
        public Tuple<int, int, Turn> step = null;

        /// <summary>
        /// 是否“天才”
        /// </summary>
        public bool success = false;

        /// <summary>
        /// 初始化9X9加边框棋盘，布尔类型
        /// 只留中心为false，其余为true
        /// </summary>
        public Aspect()
        {
            map = new bool[9, 9];
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    map[i, j] = true;
                    map[j, i] = true;
                }
            }
            map[4, 4] = false;
        }

        /// <summary>
        /// 由父棋局演化而来
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="step"></param>
        public Aspect(Aspect parent, Tuple<int, int, Turn> step)
        {
            this.map = (bool[,])parent.map.Clone();
            this.parent = parent;
            this.step = step;
            this.th = parent.th + 1;

            int i = step.Item1, j = step.Item2;

            this.map[i, j] = !this.map[i, j];
            switch (step.Item3)
            {
                case Turn.LEFT:
                    this.map[i, j - 1] = !this.map[i, j - 1];
                    this.map[i, j - 2] = !this.map[i, j - 2];
                    break;
                case Turn.RIGHT:
                    this.map[i, j + 1] = !this.map[i, j + 1];
                    this.map[i, j + 2] = !this.map[i, j + 2];
                    break;
                case Turn.UP:
                    this.map[i - 1, j] = !this.map[i - 1, j];
                    this.map[i - 2, j] = !this.map[i - 2, j];
                    break;
                case Turn.DOWN:
                    this.map[i + 1, j] = !this.map[i + 1, j];
                    this.map[i + 2, j] = !this.map[i + 2, j];
                    break;
            }

            this.success = th == 31 && map[4, 4];
        }

        /// <summary>
        /// 四个方向都有哪些可行棋步
        /// </summary>
        /// <returns></returns>
        public List<Tuple<int, int, Turn>> Steps()
        {
            List<Tuple<int, int, Turn>> tuples = new();
            #region LEFT
            if (map[1, 3] == false && map[1, 4] && map[1, 5])
            {
                tuples.Add(new(1, 5, Turn.LEFT));
            }

            if (map[2, 3] == false && map[2, 4] && map[2, 5])
            {
                tuples.Add(new(2, 5, Turn.LEFT));
            }

            if (map[6, 3] == false && map[6, 4] && map[6, 5])
            {
                tuples.Add(new(6, 5, Turn.LEFT));
            }

            if (map[7, 3] == false && map[7, 4] && map[7, 5])
            {
                tuples.Add(new(7, 5, Turn.LEFT));
            }

            for (int i = 3; i <= 5; i++)
            {
                for (int j = 1; j <= 5; j++)
                {
                    if (map[i, j] == false && map[i, j + 1] && map[i, j + 2])
                    {
                        tuples.Add(new(i, j + 2, Turn.LEFT));
                    }
                }
            }
            #endregion

            #region RIGHT
            if (map[1, 5] == false && map[1, 4] && map[1, 3])
            {
                tuples.Add(new(1, 3, Turn.RIGHT));
            }

            if (map[2, 5] == false && map[2, 4] && map[2, 3])
            {
                tuples.Add(new(2, 3, Turn.RIGHT));
            }

            if (map[6, 5] == false && map[6, 4] && map[6, 3])
            {
                tuples.Add(new(6, 3, Turn.RIGHT));
            }

            if (map[7, 5] == false && map[7, 4] && map[7, 3])
            {
                tuples.Add(new(7, 3, Turn.RIGHT));
            }

            for (int i = 3; i <= 5; i++)
            {
                for (int j = 7; j >= 3; j--)
                {
                    if (map[i, j] == false && map[i, j - 1] && map[i, j - 2])
                    {
                        tuples.Add(new(i, j - 2, Turn.RIGHT));
                    }
                }
            }
            #endregion

            #region UP
            if (map[3, 1] == false && map[4, 1] && map[5, 1])
            {
                tuples.Add(new(5, 1, Turn.UP));
            }

            if (map[3, 2] == false && map[4, 2] && map[5, 2])
            {
                tuples.Add(new(5, 2, Turn.UP));
            }

            if (map[3, 6] == false && map[4, 6] && map[5, 6])
            {
                tuples.Add(new(5, 6, Turn.UP));
            }

            if (map[3, 7] == false && map[4, 7] && map[5, 7])
            {
                tuples.Add(new(5, 7, Turn.UP));
            }

            for (int i = 1; i <= 5; i++)
            {
                for (int j = 3; j <= 5; j++)
                {
                    if (map[i, j] == false && map[i + 1, j] && map[i + 2, j])
                    {
                        tuples.Add(new(i + 2, j, Turn.UP));
                    }
                }
            }
            #endregion

            #region DOWN
            if (map[5, 1] == false && map[4, 1] && map[3, 1])
            {
                tuples.Add(new(3, 1, Turn.DOWN));
            }

            if (map[5, 2] == false && map[4, 2] && map[3, 2])
            {
                tuples.Add(new(3, 2, Turn.DOWN));
            }

            if (map[5, 6] == false && map[4, 6] && map[3, 6])
            {
                tuples.Add(new(3, 6, Turn.DOWN));
            }

            if (map[5, 7] == false && map[4, 7] && map[3, 7])
            {
                tuples.Add(new(3, 7, Turn.DOWN));
            }

            for (int i = 7; i >= 3; i--)
            {
                for (int j = 3; j <= 5; j++)
                {
                    if (map[i, j] == false && map[i - 1, j] && map[i - 2, j])
                    {
                        tuples.Add(new(i - 2, j, Turn.DOWN));
                    }
                }
            }
            #endregion

            return tuples;
        }
    }

    /// <summary>
    /// 方向常量
    /// </summary>
    public enum Turn
    {
        LEFT,
        RIGHT,
        UP,
        DOWN
    }
}
